import json
import allure
import requests


class RequestUtil(object):
    @staticmethod
    def send_requests(logger, wechat_base_url, case, access_token=None):
        """
        :param logger:日志记录器
        :param wechat_base_url:基础 URL
        :param case:测试用例数据
        :param access_token:访问令牌（可选）
        :return:响应对象
        """

        try:
            logger.info(f"正在执行的用例: {case['allure']['title']}")
            method = case.get("request", {}).get("method", "GET")  # 没有的话，默认 GET
            url = wechat_base_url + case.get("request", {}).get("url", "")  # 没有返回空
            headers = case.get("request", {}).get("headers", {})  # 没有返回空
            params = case.get("params", {})  # 没有返回空
            data = case.get("data", None)  # 没有返回空
            # 处理 access_token（如果有）
            if access_token:
                params = access_token
            # 整理传递给request的参数
            request_kwargs = {
                "method": method,
                "url": url,
                "headers": headers or None,  # 如果 headers 为空，则设为 None
                "params": params or None,  # 如果 headers 为空，则设为 None
                "data": json.dumps(data) if data else None  # 只有 data 存在才转换 JSON,否则设为 None
            }
            # 过滤掉 None 值，确保 requests 只接收有效参数
            request_kwargs = {k: v for k, v in request_kwargs.items() if v is not None}

            # 发送请求
            response = requests.request(**request_kwargs, timeout=5)
            response_json = response.json()

            # 日志记录
            logger.info(f"请求信息: {json.dumps(request_kwargs, indent=4, ensure_ascii=False)}")
            logger.info(f"返回结果: {json.dumps(response_json, indent=4, ensure_ascii=False)}")

            # 将请求和响应信息添加到 Allure 报告中
            allure.attach(json.dumps(request_kwargs, indent=4, ensure_ascii=False), name="请求信息",
                          attachment_type=allure.attachment_type.JSON)
            allure.attach(json.dumps(response_json, indent=4, ensure_ascii=False), name="响应内容",
                          attachment_type=allure.attachment_type.JSON)

            return response_json


        # 捕获 requests 相关错误，例如超时、连接失败等
        except requests.exceptions.RequestException as e:
            assert False
            # 记录完整的错误堆栈，方便排查问题。
            logger.error(f"HTTP 请求失败: {str(e)}", exc_info=True)
            # 让 pytest 能检测到错误，而不是静默失败。
            raise  # 重新抛出异常，方便 pytest 断言

        except Exception as e:
            assert False
            logger.error(f"未知错误: {str(e)}", exc_info=True)
            raise
